from PyQt6.QtWidgets import *
from PyQt6.QtCore import Qt, QDateTime, QTimer, QUrl
from PyQt6.QtGui import QDesktopServices, QFont, QIcon, QPalette, QColor
import sys
import time
from datetime import datetime, timedelta
import base64
import hmac
import hashlib
from urllib.parse import quote
import json
import os

class TokenCalculator(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("OneNET-token计算工具V3.00")
        self.setMinimumWidth(800)
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f5f6fa;
            }
            QGroupBox {
                font-size: 14px;
                font-weight: bold;
                border: 2px solid #dcdde1;
                border-radius: 8px;
                margin-top: 12px;
                padding-top: 10px;
            }
            QGroupBox::title {
                color: #2f3542;
                subcontrol-origin: margin;
                subcontrol-position: top center;
                padding: 0 10px;
            }
            QLabel {
                color: #2f3542;
                font-size: 13px;
            }
            QLineEdit {
                padding: 8px;
                border: 1px solid #dcdde1;
                border-radius: 4px;
                background: white;
                selection-background-color: #74b9ff;
                font-size: 13px;
            }
            QLineEdit:focus {
                border: 2px solid #74b9ff;
            }
            QPushButton {
                padding: 8px 15px;
                border-radius: 4px;
                background-color: #74b9ff;
                color: white;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover {
                background-color: #0984e3;
            }
            QPushButton#docButton {
                background-color: #81ecec;
                color: #2d3436;
            }
            QPushButton#docButton:hover {
                background-color: #00cec9;
            }
            QPushButton#generateButton {
                background-color: #00b894;
                font-size: 14px;
                padding: 12px 30px;
            }
            QPushButton#generateButton:hover {
                background-color: #00a884;
            }
            QComboBox {
                padding: 8px;
                border: 1px solid #dcdde1;
                border-radius: 4px;
                background: white;
            }
            QTextEdit {
                border: 1px solid #dcdde1;
                border-radius: 4px;
                background: white;
                font-family: Consolas, Monaco, monospace;
                font-size: 13px;
            }
        """)

        # 创建主窗口部件
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        
        # 主布局
        main_layout = QVBoxLayout(main_widget)
        main_layout.setSpacing(10)
        main_layout.setContentsMargins(10, 10, 10, 10)
        
        # === 左右分栏布局 ===
        split_layout = QHBoxLayout()
        
        # 左侧布局
        left_layout = QVBoxLayout()
        left_layout.setSpacing(8)
        
        # === res部分 ===
        res_group = QGroupBox("res参数设置")
        res_layout = QVBoxLayout()
        res_layout.setSpacing(5)
        
        # === 通用标签样式 ===
        label_style = """
            QLabel {
                color: #2f3542;
                font-size: 13px;
                padding: 2px;
            }
        """
        
        # === 通用输入框样式 ===
        input_style = """
            QLineEdit {
                padding: 8px;
                border: 1px solid #dcdde1;
                border-radius: 4px;
                background: white;
                selection-background-color: #74b9ff;
                font-size: 13px;
                min-height: 20px;
            }
            QLineEdit:focus {
                border: 2px solid #74b9ff;
            }
        """
        
        # === 提示文本样式 ===
        tips_style = """
            QLabel {
                color: #636e72;
                font-size: 11px;
                padding: 2px;
                margin-top: 2px;
            }
        """
        
        # === 标签宽度统一设置 ===
        LABEL_WIDTH = 60
        
        # res输入框和说明
        res_input_layout = QHBoxLayout()
        res_label = QLabel("res:")
        res_label.setFixedWidth(LABEL_WIDTH)
        res_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        res_label.setStyleSheet(label_style)
        
        self.res_input = QLineEdit("")
        self.res_input.setStyleSheet(input_style)
        
        # 添加到水平布局
        res_input_layout.addWidget(res_label)
        res_input_layout.addWidget(self.res_input)
        
        # res说明（简化为单行）
        res_tips = QLabel("设备接入: products/{pid}/devices/{name} | API鉴权: userid/{uid}")
        res_tips.setStyleSheet(tips_style)
        res_tips.setWordWrap(True)  # 允许文字换行
        
        # === 文档链接按钮 ===
        doc_layout = QHBoxLayout()
        doc_layout.addStretch()
        
        self.doc_btn1 = QPushButton("➡设备接入文档")
        self.doc_btn1.setObjectName("docButton")
        self.doc_btn1.clicked.connect(lambda: QDesktopServices.openUrl(
            QUrl("https://open.iot.10086.cn/doc/v5/fuse/detail/1486")))
        
        self.doc_btn2 = QPushButton("➡API鉴权文档")
        self.doc_btn2.setObjectName("docButton")
        self.doc_btn2.clicked.connect(lambda: QDesktopServices.openUrl(
            QUrl("https://open.iot.10086.cn/doc/v5/fuse/detail/1464")))
        
        doc_layout.addWidget(self.doc_btn1)
        doc_layout.addWidget(self.doc_btn2)
        doc_layout.addStretch()
        
        # 添加到垂直布局
        res_layout.addLayout(res_input_layout)
        res_layout.addWidget(res_tips)
        res_layout.addLayout(doc_layout)  # 添加文档按钮布局
        
        # 设置组布局
        res_group.setLayout(res_layout)
        left_layout.addWidget(res_group)
        
        # === et时间设置部分 ===
        time_group = QGroupBox("时间设置")
        time_layout = QVBoxLayout()
        time_layout.setSpacing(5)
        
        # 创建日历控件
        self.calendar = QCalendarWidget(self)
        self.calendar.setWindowFlags(Qt.WindowType.Popup)  # 设置为弹出窗口
        self.calendar.clicked.connect(self.calendar_date_selected)
        # 设置日历样式
        self.calendar.setStyleSheet("""
            QCalendarWidget {
                background-color: white;
                border: 1px solid #dcdde1;
            }
            QCalendarWidget QToolButton {
                color: #2f3542;
                background-color: transparent;
                padding: 5px;
            }
            QCalendarWidget QMenu {
                background-color: white;
            }
            QCalendarWidget QSpinBox {
                background-color: white;
                selection-background-color: #74b9ff;
            }
            QCalendarWidget QTableView {
                selection-background-color: #74b9ff;
                selection-color: white;
            }
        """)
        
        # et输入和时间选择布局
        et_input_layout = QHBoxLayout()
        et_label = QLabel("et:")
        et_label.setFixedWidth(LABEL_WIDTH)
        et_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        et_label.setStyleSheet(label_style)
        
        # et输入框
        self.et_input = QLineEdit(str(int(time.time() + 3600*24*30)))
        self.et_input.textChanged.connect(self.validate_timestamp)
        self.et_input.setStyleSheet(input_style)
        
        # 时间选择按钮
        self.date_time_btn = QPushButton("选择时间")
        self.date_time_btn.clicked.connect(self.show_calendar)
        
        et_input_layout.addWidget(et_label)
        et_input_layout.addWidget(self.et_input)
        et_input_layout.addWidget(self.date_time_btn)
        
        # 时间戳错误提示标签
        self.et_error_label = QLabel()
        self.et_error_label.setStyleSheet("""
            QLabel {
                color: #e74c3c;
                font-size: 11px;
                padding: 2px;
                margin-left: 65px;
            }
        """)
        self.et_error_label.hide()  # 默认隐藏错误提示
        
        # 可读时间显示 - 移到这里创
        self.readable_time = QLabel()
        self.readable_time.setStyleSheet(tips_style)
        
        # 快捷时间按钮布局
        time_buttons_layout = QHBoxLayout()
        time_buttons_layout.setSpacing(5)
        
        # 添加到布局
        time_layout.addLayout(et_input_layout)
        time_layout.addWidget(self.et_error_label)
        time_layout.addWidget(self.readable_time)  # 现在可以安全地添加了
        time_layout.addLayout(time_buttons_layout)
        
        # 添加快捷时间按钮
        quick_times = [
            ("+1天", 0, 1),
            ("+7天", 0, 7),
            ("+1月", 0, 30),
            ("+1年", 0, 365)
        ]
        
        for btn_text, hours, days in quick_times:
            btn = QPushButton(btn_text)
            btn.setFixedWidth(60)
            btn.setFixedHeight(25)
            btn.setStyleSheet("""
                QPushButton {
                    background-color: #a8e6cf;
                    color: #2d3436;
                    font-size: 12px;
                    padding: 3px;
                }
                QPushButton:hover {
                    background-color: #88d7b5;
                }
            """)
            btn.clicked.connect(lambda checked, h=hours, d=days: self.add_time(hours=h, days=d))
            time_buttons_layout.addWidget(btn)
        
        time_buttons_layout.addStretch()
        
        # 设置时间组样式（与res组保持一致）
        time_group.setStyleSheet("""
            QGroupBox {
                font-size: 14px;
                font-weight: bold;
                border: 2px solid #dcdde1;
                border-radius: 8px;
                margin-top: 12px;
                padding: 10px;
            }
            QLabel {
                padding: 2px;
            }
        """)
        
        time_group.setLayout(time_layout)
        left_layout.addWidget(time_group)
        
        # 右侧布局
        right_layout = QVBoxLayout()
        right_layout.setSpacing(8)
        
        # === 其他参数部分 ===
        params_group = QGroupBox("其他参数")
        params_layout = QGridLayout()
        params_layout.setSpacing(8)
        
        # key输入框
        key_label = QLabel("key:")
        key_label.setFixedWidth(LABEL_WIDTH)
        key_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        key_label.setStyleSheet(label_style)
        self.key_input = QLineEdit("")
        self.key_input.setStyleSheet(input_style)
        key_tips = QLabel("请输入对应KEY")
        key_tips.setStyleSheet(tips_style)
        
        # method选择
        method_label = QLabel("method:")
        method_label.setFixedWidth(LABEL_WIDTH)
        method_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        method_label.setStyleSheet(label_style)
        self.method_combo = QComboBox()
        self.method_combo.addItems(["md5", "sha1", "sha256"])
        self.method_combo.setFixedWidth(80)
        method_tips = QLabel("支持md5、sha1、sha256三种签名方式")
        method_tips.setStyleSheet(tips_style)
        
        # version选择
        version_label = QLabel("version:")
        version_label.setFixedWidth(LABEL_WIDTH)
        version_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        version_label.setStyleSheet(label_style)
        self.version_combo = QComboBox()
        self.version_combo.addItems(["2018-10-31", "2022-05-01", "2020-05-29"])
        version_tips = QLabel(
            "• 2018-10-31: 设备接入\n"
            "• 2022-05-01: 新平台API调用\n"
            "• 2020-05-29: Studio-API调用"
        )
        version_tips.setStyleSheet(tips_style)
        
        # 使用网格布局添加控件
        params_layout.addWidget(key_label, 0, 0)
        params_layout.addWidget(self.key_input, 0, 1)
        params_layout.addWidget(key_tips, 1, 1)
        
        params_layout.addWidget(method_label, 2, 0)
        params_layout.addWidget(self.method_combo, 2, 1)
        params_layout.addWidget(method_tips, 3, 1)
        
        params_layout.addWidget(version_label, 4, 0)
        params_layout.addWidget(self.version_combo, 4, 1)
        params_layout.addWidget(version_tips, 5, 1)
        
        # 设置列拉伸
        params_layout.setColumnStretch(1, 1)
        
        # 设置组件样式
        params_group.setStyleSheet("""
            QGroupBox {
                font-size: 13px;
                font-weight: bold;
                border: 2px solid #dcdde1;
                border-radius: 8px;
                margin-top: 12px;
                padding: 10px;
            }
            QLabel {
                padding: 2px;
            }
            QComboBox {
                padding: 5px;
                border: 1px solid #dcdde1;
                border-radius: 4px;
                background: white;
            }
            QComboBox:focus {
                border: 2px solid #74b9ff;
            }
        """)
        
        params_group.setLayout(params_layout)
        right_layout.addWidget(params_group)
        
        # 确保所有下拉框样式一致
        combo_style = """
            QComboBox {
                padding: 5px;
                border: 1px solid #dcdde1;
                border-radius: 4px;
                background: white;
                min-width: 100px;
            }
            QComboBox:focus {
                border: 2px solid #74b9ff;
            }
            QComboBox::drop-down {
                border: none;
                padding-right: 5px;
            }
            QComboBox::down-arrow {
                image: url(down_arrow.png);
                width: 12px;
                height: 12px;
            }
        """
        
        self.method_combo.setStyleSheet(combo_style)
        self.version_combo.setStyleSheet(combo_style)
        
        # 添加左右布局到分栏
        split_layout.addLayout(left_layout)
        split_layout.addLayout(right_layout)
        main_layout.addLayout(split_layout)
        
        # === 配置管理（美化和说明）===
        config_group = QGroupBox("配置管理")
        config_group.setStyleSheet("""
            QGroupBox {
                font-size: 13px;
                font-weight: bold;
                border: 2px solid #dcdde1;
                border-radius: 8px;
                margin-top: 12px;
                padding: 10px;
            }
        """)
        
        config_layout = QVBoxLayout()
        
        # 添加配置管理说明
        config_tips = QLabel(
            "• 可保存常用的参数组合，方便快速调用\n"
            "• 最多可保存10个置\n"
            "• 不输入配置名称将使用时间戳命名"
        )
        config_tips.setStyleSheet("color: #636e72; font-size: 11px; padding: 5px;")
        
        # 配置操作区域
        config_controls = QHBoxLayout()
        
        self.config_name_input = QLineEdit()
        self.config_name_input.setPlaceholderText("输入配置名称用以保存")
        self.config_name_input.setFixedWidth(120)
        
        self.config_combo = QComboBox()
        self.config_combo.setFixedWidth(150)
        self.config_combo.setPlaceholderText("选择已保存的配置")
        
        save_config_btn = QPushButton("保存")
        save_config_btn.setFixedWidth(60)
        save_config_btn.clicked.connect(self.save_config)
        save_config_btn.setToolTip("保存当前参数为新配置")
        
        delete_config_btn = QPushButton("删除")
        delete_config_btn.setFixedWidth(60)
        delete_config_btn.clicked.connect(self.delete_config)
        delete_config_btn.setToolTip("删除选中的配置")
        
        config_controls.addWidget(self.config_name_input)
        config_controls.addWidget(self.config_combo)
        config_controls.addWidget(save_config_btn)
        config_controls.addWidget(delete_config_btn)
        config_controls.addStretch()
        
        config_layout.addWidget(config_tips)
        config_layout.addLayout(config_controls)
        
        config_group.setLayout(config_layout)
        main_layout.addWidget(config_group)
        
        # === Token生成部分 ===
        result_layout = QVBoxLayout()
        generate_btn = QPushButton("生成Token")
        generate_btn.setObjectName("generateButton")
        generate_btn.setFixedHeight(40)
        generate_btn.clicked.connect(self.generate_token)  # 连接生成按钮事件
        
        self.result_text = QTextEdit()
        self.result_text.setFixedHeight(80)
        self.result_text.setPlaceholderText("Token将在这里显示...")
        
        result_layout.addWidget(generate_btn)
        result_layout.addWidget(self.result_text)
        main_layout.addLayout(result_layout)
        
        # 加载配置文件
        self.config_file = "token_configs.json"
        self.configs = {}
        self.load_saved_configs()
        
        # 配置选择事件
        self.config_combo.currentTextChanged.connect(self.load_config)
        
        # 添加时间更新定时器
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_readable_time)
        self.timer.start(1000)  # 每秒更新一次
        
        # 初始化显示可读时间
        self.update_readable_time()

    def generate_token(self):
        """生成Token的方法"""
        try:
            # 获取输入值
            res = self.res_input.text().strip()
            et = self.et_input.text().strip()
            key = self.key_input.text().strip()
            method = self.method_combo.currentText()
            version = self.version_combo.currentText()
            
            # 验证输入
            if not all([res, et, key]):
                self.result_text.setText("错误：请填写所有必需参数！")
                return
            
            try:
                et = int(et)
            except ValueError:
                self.result_text.setText("错误：et必须是有效的时间戳！")
                return
            
            # 对access_key进行decode
            try:
                key = base64.b64decode(key)
            except Exception:
                self.result_text.setText("错误：key格式不正确，请确保是Base64编码的字符串！")
                return
            
            # 构造待签名字符串 - 注意这里的换行符
            sign_str = f"{et}\n{method}\n{res}\n{version}"
            
            # 根据选择的方法进行签名
            if method == "md5":
                hash_method = "md5"
            elif method == "sha1":
                hash_method = "sha1"
            elif method == "sha256":
                hash_method = "sha256"
            else:
                self.result_text.setText("错误：不支持的签名方法！")
                return
            
            # 计算签名
            sign_b = hmac.new(key=key, msg=sign_str.encode(), digestmod=hash_method)
            sign = base64.b64encode(sign_b.digest()).decode()
            
            # URL编码处理
            sign = quote(sign, safe='')
            res = quote(res, safe='')
            
            # 生成token
            token = f"version={version}&res={res}&et={et}&method={method}&sign={sign}"
            
            # 显示结果
            self.result_text.setPlainText(token)
            
            # 添加复制按钮功能
            QApplication.clipboard().setText(token)
            self.result_text.append("\n✓ Token已自动复制到剪贴板")
            
        except Exception as e:
            self.result_text.setText(f"错误：生成Token时发生异常 - {str(e)}")

    def update_readable_time(self):
        """更新可读时间显示"""
        try:
            timestamp = int(self.et_input.text())
            readable_time = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
            self.readable_time.setText(f"过期时间: {readable_time}")
        except Exception as e:
            self.readable_time.setText("时间格式错误")
            print(f"时间格式转换错误: {str(e)}")  # 记录详细错误信息

    def add_time(self, hours=0, days=0):
        """添加指定的时间"""
        try:
            current_timestamp = int(self.et_input.text())
            delta = timedelta(hours=hours, days=days)
            new_timestamp = current_timestamp + int(delta.total_seconds())
            self.et_input.setText(str(new_timestamp))
            self.update_readable_time()
        except ValueError:
            self.readable_time.setText("时间格式错误")

    def load_saved_configs(self):
        """加载保存的配置"""
        try:
            if os.path.exists(self.config_file):
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    self.configs = json.load(f)
                    self.config_combo.clear()
                    self.config_combo.addItems(self.configs.keys())
            else:
                self.configs = {}
        except Exception as e:
            self.configs = {}
            print(f"加载配置文件失败: {str(e)}")

    def save_config(self):
        """保存当前配置"""
        try:
            # 获取配置名
            name = self.config_name_input.text().strip()
            if not name:
                # 如果未输入名称，使用时间戳作为默认名称
                name = datetime.now().strftime("%Y%m%d_%H%M%S")
            
            # 检查配置数量限制
            if len(self.configs) >= 10 and name not in self.configs:
                QMessageBox.warning(self, "警告", "最多只能保存10个配置！请先删除一些配置。")
                return
            
            # 保存当前配置
            config = {
                'res': self.res_input.text(),
                'et': self.et_input.text(),
                'key': self.key_input.text(),
                'method': self.method_combo.currentText(),
                'version': self.version_combo.currentText()
            }
            
            self.configs[name] = config
            
            # 保存到文件
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(self.configs, f, ensure_ascii=False, indent=2)
            
            # 更新下拉框
            self.config_combo.clear()
            self.config_combo.addItems(self.configs.keys())
            self.config_combo.setCurrentText(name)
            
            QMessageBox.information(self, "成功", f"配置 '{name}' 已保存")
            self.config_name_input.clear()
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"保存配置失败: {str(e)}")

    def load_config(self, name):
        """加载选中的配置"""
        if not name:
            return
            
        try:
            config = self.configs.get(name)
            if config:
                self.res_input.setText(config['res'])
                self.et_input.setText(config['et'])
                self.key_input.setText(config['key'])
                self.method_combo.setCurrentText(config['method'])
                self.version_combo.setCurrentText(config['version'])
        except Exception as e:
            QMessageBox.warning(self, "错误", f"加载配置失败: {str(e)}")

    def delete_config(self):
        """删除选中的配置"""
        name = self.config_combo.currentText()
        if not name:
            return
        
        try:
            reply = QMessageBox.question(self, '确认删除', 
                                       f"确定要删除配置 '{name}' 吗？",
                                       QMessageBox.StandardButton.Yes | 
                                       QMessageBox.StandardButton.No)
            
            if reply == QMessageBox.StandardButton.Yes:
                del self.configs[name]
                
                # 保存到文件
                with open(self.config_file, 'w', encoding='utf-8') as f:
                    json.dump(self.configs, f, ensure_ascii=False, indent=2)
                
                # 更新下拉框
                self.config_combo.clear()
                self.config_combo.addItems(self.configs.keys())
                
                QMessageBox.information(self, "成功", f"配置 '{name}' 已删除")
        except Exception as e:
            QMessageBox.warning(self, "错误", f"删除配置失败: {str(e)}")

    def show_calendar(self):
        """显示日历选择器"""
        try:
            # 根据当前时间戳更新日历的选中日期
            current_timestamp = int(self.et_input.text())
            current_date = datetime.fromtimestamp(current_timestamp).date()
            
            # 先设置当前页面显示的年月，再设置选中日期
            self.calendar.setSelectedDate(current_date)
            self.calendar.setCurrentPage(current_date.year, current_date.month)
            
        except ValueError:
            # 如果时间戳无效，使用当前日期
            now = datetime.now().date()
            self.calendar.setSelectedDate(now)
            self.calendar.setCurrentPage(now.year, now.month)
        
        # 显示日历并定位到按钮下方
        btn_pos = self.date_time_btn.mapToGlobal(self.date_time_btn.rect().bottomLeft())
        self.calendar.move(btn_pos)
        self.calendar.show()

    def calendar_date_selected(self, date):
        """当选择日期时更新时间戳"""
        try:
            # 使用选择的日期和当前时间
            current_time = datetime.now().time()
            selected_datetime = datetime.combine(date.toPyDate(), current_time)
            timestamp = int(selected_datetime.timestamp())
            self.et_input.setText(str(timestamp))
            self.update_readable_time()
            self.calendar.hide()
        except Exception as e:
            self.readable_time.setText(f"时间转换错误: {str(e)}")

    def validate_timestamp(self, text):
        """验证时间戳输入"""
        try:
            if not text:
                self.et_error_label.setText("时间戳不能为空")
                self.et_error_label.show()
                self.readable_time.setText("时间格式错误")
                return False
            
            # 检查是否包含非法字符
            if not text.isdigit():
                self.et_error_label.setText("时间戳只能包含数字")
                self.et_error_label.show()
                self.readable_time.setText("时间格式错误")
                return False
            
            timestamp = int(text)
            current_time = int(time.time())
            
            # 检查时间戳范围
            if timestamp < 0:
                self.et_error_label.setText("时间戳不能为负数")
                self.et_error_label.show()
                self.readable_time.setText("时间格式错误")
                return False
            
            if timestamp < current_time:
                self.et_error_label.setText("时间戳不能小于当前时间")
                self.et_error_label.show()
                self.readable_time.setText("时间格式错误")
                return False
            
            if timestamp > current_time + 3600*24*365*10:  # 最大10年
                self.et_error_label.setText("时间戳不能超过10年")
                self.et_error_label.show()
                self.readable_time.setText("时间格式错误")
                return False
            
            # 检查时间戳是否在合理范围内
            try:
                datetime.fromtimestamp(timestamp)
            except (ValueError, OSError):
                self.et_error_label.setText("无效的时间戳")
                self.et_error_label.show()
                self.readable_time.setText("时间格式错误")
                return False
            
            # 输入有效，隐藏错误提示
            self.et_error_label.hide()
            self.update_readable_time()
            return True
        
        except Exception as e:
            self.et_error_label.setText("请输入有效的时间戳")
            self.et_error_label.show()
            self.readable_time.setText("时间格式错误")
            print(f"时间戳验证错误: {str(e)}")  # 记录详细错误信息
            return False

def main():
    app = QApplication(sys.argv)
    window = TokenCalculator()
    window.show()
    sys.exit(app.exec())

if __name__ == '__main__':
    main() 